{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# Python操作Excel",
   "id": "d7afe1f1b76c6e24"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 1. Python操作Excel之 新建、修改、读取",
   "id": "947f3eb36490d9f0"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 1.1. 读取Excel",
   "id": "70e766dccdeb77d5"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-02T06:38:36.612113Z",
     "start_time": "2025-09-02T06:38:36.601322Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import os\n",
    "from curses import start_color\n",
    "from re import Pattern\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "path = 'D:/2506A/monty03/day07/file/'\n",
    "\n",
    "# 读取Excel\n",
    "df = pd.read_excel(path + 'example.xlsx')\n",
    "print(\"当前工作目录:\", os.getcwd())\n",
    "\n",
    "print(df)"
   ],
   "id": "d1b1e172537e83cc",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当前工作目录: C:\\Windows\\System32\n",
      "    姓名  年龄\n",
      "0  聂茹凤  19\n",
      "1  谭鑫宇  17\n",
      "2  韩耀祖  11\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 1.2. 写入Excel\n",
   "id": "dadddcfed59c4aed"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-02T06:38:39.863819Z",
     "start_time": "2025-09-02T06:38:39.845432Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 创建一个DataFrame对象\n",
    "data = {\n",
    "    '姓名':['刘千琪','刘亦菲','王丽坤'],\n",
    "    '年龄':[22,37,35],\n",
    "    '地址':['吉林省长春市', '北京市海淀区','内蒙古自治区赤峰市']\n",
    "}\n",
    "\n",
    "df = pd.DataFrame(data)\n",
    "\n",
    "# 将DataFrame写如Excel\n",
    "df.to_excel(path + '学生.xlsx',index=False)\n",
    "print('写出完毕')\n"
   ],
   "id": "fc5a656dc38d98a9",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "写出完毕\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 1.3. 修改Excel\n",
   "id": "5638dc04ef3fc6f6"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-02T06:46:22.299500Z",
     "start_time": "2025-09-02T06:46:22.259275Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from openpyxl import load_workbook\n",
    "\n",
    "# 加载要修改的Excel\n",
    "wb = load_workbook(path + '学生.xlsx')\n",
    "\n",
    "# 获取工作表\n",
    "ws = wb.active\n",
    "\n",
    "# 修改Excel\n",
    "ws['A2'] = '刘德华'\n",
    "\n",
    "# 保存修改后的Excel\n",
    "wb.save(path + '学生.xlsx')"
   ],
   "id": "a0fc27283c242448",
   "outputs": [],
   "execution_count": 9
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "##  2. 批量处理Excel",
   "id": "5d451d01d946736d"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 2.1 批量读取",
   "id": "b4ca7c9b13d546c3"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-02T06:55:09.954201Z",
     "start_time": "2025-09-02T06:55:09.912172Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 获取包含所有Excel工作表的文件夹\n",
    "os.chdir(path)\n",
    "\n",
    "# 获取所有的Excel\n",
    "files = [file for file in os.listdir() if file.endswith('.xlsx')]\n",
    "\n",
    "# 读取每一个Excel并打印到控制台\n",
    "for file in files:\n",
    "    df = pd.read_excel(file)\n",
    "\n",
    "    print(df)\n",
    "\n",
    "\n"
   ],
   "id": "1c64f8d3bfb07917",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    姓名  年龄\n",
      "0  聂茹凤  19\n",
      "1  谭鑫宇  17\n",
      "2  韩耀祖  11\n",
      "    姓名  年龄         地址\n",
      "0  刘德华  22     吉林省长春市\n",
      "1  刘亦菲  37     北京市海淀区\n",
      "2  王丽坤  35  内蒙古自治区赤峰市\n"
     ]
    }
   ],
   "execution_count": 13
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 2.2 写出多个表",
   "id": "a9d1c75e87c7c085"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-02T07:10:58.402820Z",
     "start_time": "2025-09-02T07:10:58.313057Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 创建多个DataFrame对象\n",
    "data1 = {\n",
    "    '书名':['《三国演义》','《红楼梦》','《水浒传》','《西游记》'],\n",
    "    '作者':['罗贯中','曹雪芹','施耐庵','吴承恩']\n",
    "}\n",
    "data2 = {\n",
    "    '城市':['北京','上海','广州','深圳'],\n",
    "    '邮编':['100000','200000','510000','518000']\n",
    "}\n",
    "data3 = {\n",
    "    '水果':['苹果','香蕉','梨','石榴','榴莲'],\n",
    "    '单价':[4.2, 6.8, 1.5, 9.6, 25.9]\n",
    "}\n",
    "\n",
    "df1 = pd.DataFrame(data1)\n",
    "df2 = pd.DataFrame(data2)\n",
    "df3 = pd.DataFrame(data3)\n",
    "\n",
    "# 我们可以把三个dataframe放在一个列表中，然后循环写出\n",
    "dfs = [df1, df2, df3]\n",
    "\n",
    "# enumerate() 是Python内置函数，用于给可迭代对象（如列表、元组、字符串等）添加索引计数器。\n",
    "for i,df in enumerate(dfs,start=1):\n",
    "    # 给每一个df创建一个文件名\n",
    "    file_name = f'表{i}.xlsx'\n",
    "    df.to_excel(path + file_name,index=False)\n",
    "    print(f'DataFrame{i}已经写如{file_name}')"
   ],
   "id": "f0ae4e9c2b696b93",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DataFrame1已经写如表1.xlsx\n",
      "DataFrame2已经写如表2.xlsx\n",
      "DataFrame3已经写如表3.xlsx\n"
     ]
    }
   ],
   "execution_count": 19
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 2.3 批量修改Excel",
   "id": "4a12f4c130656cd"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-02T07:16:43.680842Z",
     "start_time": "2025-09-02T07:16:43.587434Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from openpyxl import Workbook\n",
    "from openpyxl.styles import Font, Alignment, PatternFill, Border, Side\n",
    "\n",
    "# 创建一个工作簿和工作表\n",
    "wb = Workbook()\n",
    "ws = wb.active\n",
    "\n",
    "# 定义字体样式\n",
    "font = Font(bold=True, size=14)\n",
    "\n",
    "# 定义对齐样式\n",
    "alignment = Alignment(horizontal='center', vertical='center')\n",
    "\n",
    "# 定义填充样式\n",
    "fill = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')\n",
    "\n",
    "# 定义边框样式 thin 细边框 medium'：中等边框'thick'：粗边框\n",
    "side = Side(style='thin')\n",
    "border = Border(left=side, right=side, top=side, bottom=side)\n",
    "\n",
    "# 应用样式到单元格\n",
    "for row in ws.iter_rows(min_row=1, max_row=1, min_col=1, max_col=3):\n",
    "    for cell in row:\n",
    "        cell.font = font\n",
    "        cell.alignment = alignment\n",
    "        cell.fill = fill\n",
    "        cell.border = border\n",
    "\n",
    "# 保存工作簿\n",
    "wb.save('styled.xlsx')\n"
   ],
   "id": "135faed6a9831813",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['表1.xlsx', '表2.xlsx', '表3.xlsx']\n",
      "表1.xlsx已经修改完成\n",
      "表2.xlsx已经修改完成\n",
      "表3.xlsx已经修改完成\n"
     ]
    }
   ],
   "execution_count": 22
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 3. Python Excel数据格式化和样式设置",
   "id": "83a723caf58f8e8d"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 3.1 数据格式化\n",
    "- iter_rows(\n",
    "    min_row=None,      # 起始行号\n",
    "    max_row=None,      # 结束行号\n",
    "    min_col=None,      # 起始列号\n",
    "    max_col=None,      # 结束列号\n",
    "    values_only=False  # 是否只返回值（而不是Cell对象）\n",
    ")\n"
   ],
   "id": "a0967bedd1b1a1dc"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-02T08:00:00.675619Z",
     "start_time": "2025-09-02T08:00:00.579315Z"
    }
   },
   "cell_type": "code",
   "source": [
    "## 修改表1表2，表3中所有的数字类型保留两位小数\n",
    "\n",
    "#1. 先找到文件夹\n",
    "os.chdir(path)\n",
    "# 2. 在找到要修改的Excel\n",
    "files = [file for file in os.listdir() if file.endswith('.xlsx') and file.startswith('表')]\n",
    "\n",
    "# 3. 修改每一个表\n",
    "for file in files:\n",
    "    # 加载每一个Excel\n",
    "    wb = load_workbook(file)\n",
    "\n",
    "    # 打开Excel\n",
    "    ws = wb.active\n",
    "\n",
    "    # 创建一个数字类型的样式，设置数字类型的样式，保留两位小数\n",
    "    for row in ws.iter_rows():\n",
    "        for cell in row:\n",
    "            if isinstance(cell.value, (int,float)):\n",
    "                 cell.number_format = '0.00'\n",
    "    wb.save(path + file)\n",
    "    print(f'{file}修改完成')\n"
   ],
   "id": "78f1c46cfee07469",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "表1.xlsx修改完成\n",
      "表2.xlsx修改完成\n",
      "表3.xlsx修改完成\n"
     ]
    }
   ],
   "execution_count": 33
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-02T07:59:48.613207Z",
     "start_time": "2025-09-02T07:59:48.595960Z"
    }
   },
   "cell_type": "code",
   "source": [
    "\n",
    "file = os.path.join(path, '表1.xlsx')\n",
    "\n",
    "wb = load_workbook(file)\n",
    "ws = wb.active\n",
    "\n",
    "for row  in ws.iter_rows():\n",
    "    for cell in row:\n",
    "        # 获取所有数字类型的值\n",
    "        # print(cell.value)\n",
    "        if isinstance(cell.value, (int,float)):\n",
    "            print(cell.value)\n",
    "\n"
   ],
   "id": "8b27621fc342a3a",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "39.2\n",
      "41.8\n",
      "53\n",
      "66\n"
     ]
    }
   ],
   "execution_count": 32
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 3.2 设置单元格的样式",
   "id": "159cd707108340a2"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-02T08:49:16.291111Z",
     "start_time": "2025-09-02T08:49:16.252845Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 正确导入方式\n",
    "from openpyxl import Workbook\n",
    "from openpyxl.styles import Alignment, PatternFill, Font\n",
    "\n",
    "\n",
    "# 创建一个工作簿和工作表\n",
    "wb = Workbook()\n",
    "ws = wb.active\n",
    "\n",
    "# 定义字体样式\n",
    "font = Font(name='仿宋', size=18,bold=True)\n",
    "\n",
    "# 定义对齐方式\n",
    "alignment = Alignment(horizontal='center',vertical='center')\n",
    "\n",
    "# # 定义填充样式\n",
    "fill = PatternFill(patternType='solid',fgColor='FFFF0000')\n",
    "\n",
    "\n",
    "\n",
    "# 应用样式到单元格\n",
    "for row in ws.iter_rows(min_row=1,max_row=5,min_col=1,max_col=5):\n",
    "    for cell in row:\n",
    "        cell.fill = fill\n",
    "        cell.alignment = alignment\n",
    "        cell.font = font\n",
    "\n",
    "\n",
    "wb.save(path + '自定义的.xlsx')\n",
    "\n"
   ],
   "id": "528259fc35be10e1",
   "outputs": [],
   "execution_count": 45
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 4. 数据清洗",
   "id": "ab52c67af123ced9"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-02T09:15:40.709564Z",
     "start_time": "2025-09-02T09:15:40.687250Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 读取Excel\n",
    "df = pd.read_excel(path + '成绩.xlsx')\n",
    "\n",
    "# 去除重复的行\n",
    "df.drop_duplicates(inplace=True)\n",
    "\n",
    "# 处理缺失值，可以选择填充或者删除\n",
    "df.ffill(inplace=True)\n",
    "# df.dropna(inplace=True)\n",
    "\n",
    "# 过滤异常值 比如年龄大于100或者小于0都属于异常\n",
    "df = df[(df['年龄'] < 100) & (df['年龄'] > 0)]\n",
    "\n",
    "\n",
    "\n",
    "print(df)\n"
   ],
   "id": "b8bd4a4c776d1539",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   序号   姓名  年龄    成绩\n",
      "2   3  韩耀祖  18  88.0\n",
      "3   4  刘千琪  16  88.0\n",
      "4   5  崔龙腾  21  76.0\n",
      "5   6  李欣桐  20  93.0\n"
     ]
    }
   ],
   "execution_count": 74
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-02T09:21:17.626118Z",
     "start_time": "2025-09-02T09:21:17.603442Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 将姓名列拆分成姓和名字\n",
    "# 读取Excel\n",
    "df = pd.read_excel(path + '成绩.xlsx')\n",
    "\n",
    "df['姓'] = df['姓名'].str[0]\n",
    "df['名字'] = df['姓名'].str[1:]\n",
    "print(df)\n",
    "\n",
    "\n"
   ],
   "id": "38bcaaefdefdb834",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   序号   姓名   年龄    成绩  姓  名字\n",
      "0   1  聂茹凤  120  95.0  聂  茹凤\n",
      "1   2  谭鑫宇   -9   NaN  谭  鑫宇\n",
      "2   3  韩耀祖   18  88.0  韩  耀祖\n",
      "3   4  刘千琪   16   NaN  刘  千琪\n",
      "4   5  崔龙腾   21  76.0  崔  龙腾\n",
      "5   6  李欣桐   20  93.0  李  欣桐\n",
      "6   1  聂茹凤  120  95.0  聂  茹凤\n",
      "7   2  谭鑫宇   -9   NaN  谭  鑫宇\n"
     ]
    }
   ],
   "execution_count": 84
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 5. 数据可视化",
   "id": "e7cc38d44c7a040e"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-02T09:28:17.540675Z",
     "start_time": "2025-09-02T09:28:17.345551Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 读取Excel\n",
    "df = pd.read_excel(path + '成绩.xlsx')\n",
    "\n",
    "# 去除重复的行\n",
    "df.drop_duplicates(inplace=True)\n",
    "\n",
    "# 处理缺失值，可以选择填充或者删除\n",
    "df.ffill(inplace=True)\n",
    "\n",
    "df = df[(df['年龄'] < 100) & (df['年龄'] > 0)]\n",
    "\n",
    "\n",
    "\n",
    "# 画图\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 设置中文字体\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']  # 黑体、微软雅黑\n",
    "plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题\n",
    "\n",
    "# 画柱状图\n",
    "plt.bar(df['姓名'], df['成绩'])\n",
    "\n",
    "plt.show()"
   ],
   "id": "a6d197a7bc301a7a",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 88
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
